/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dao;

import dao.exceptions.IllegalOrphanException;
import dao.exceptions.NonexistentEntityException;
import dominio.CompraMateriaprima;
import dominio.Fornecedor;
import dominio.MateriaPrima;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

/**
 *
 * @author Gutto
 */
public class ManterMateriaPrimaDAO {

    public ManterMateriaPrimaDAO() {
        emf = Persistence.createEntityManagerFactory("SIGITPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(MateriaPrima materiaPrima) {
        if (materiaPrima.getFornecedorList() == null) {
            materiaPrima.setFornecedorList(new ArrayList<Fornecedor>());
        }
        if (materiaPrima.getCompraMateriaprimaList() == null) {
            materiaPrima.setCompraMateriaprimaList(new ArrayList<CompraMateriaprima>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Fornecedor> attachedFornecedorList = new ArrayList<Fornecedor>();
            for (Fornecedor fornecedorListFornecedorToAttach : materiaPrima.getFornecedorList()) {
                fornecedorListFornecedorToAttach = em.getReference(fornecedorListFornecedorToAttach.getClass(), fornecedorListFornecedorToAttach.getCodigo());
                attachedFornecedorList.add(fornecedorListFornecedorToAttach);
            }
            materiaPrima.setFornecedorList(attachedFornecedorList);
            List<CompraMateriaprima> attachedCompraMateriaprimaList = new ArrayList<CompraMateriaprima>();
            for (CompraMateriaprima compraMateriaprimaListCompraMateriaprimaToAttach : materiaPrima.getCompraMateriaprimaList()) {
                compraMateriaprimaListCompraMateriaprimaToAttach = em.getReference(compraMateriaprimaListCompraMateriaprimaToAttach.getClass(), compraMateriaprimaListCompraMateriaprimaToAttach.getCompraMateriaprimaPK());
                attachedCompraMateriaprimaList.add(compraMateriaprimaListCompraMateriaprimaToAttach);
            }
            materiaPrima.setCompraMateriaprimaList(attachedCompraMateriaprimaList);
            em.persist(materiaPrima);
            for (Fornecedor fornecedorListFornecedor : materiaPrima.getFornecedorList()) {
                fornecedorListFornecedor.getMateriaprimaList().add(materiaPrima);
                fornecedorListFornecedor = em.merge(fornecedorListFornecedor);
            }
            for (CompraMateriaprima compraMateriaprimaListCompraMateriaprima : materiaPrima.getCompraMateriaprimaList()) {
                MateriaPrima oldMateriaprimaOfCompraMateriaprimaListCompraMateriaprima = compraMateriaprimaListCompraMateriaprima.getMateriaprima();
                compraMateriaprimaListCompraMateriaprima.setMateriaprima(materiaPrima);
                compraMateriaprimaListCompraMateriaprima = em.merge(compraMateriaprimaListCompraMateriaprima);
                if (oldMateriaprimaOfCompraMateriaprimaListCompraMateriaprima != null) {
                    oldMateriaprimaOfCompraMateriaprimaListCompraMateriaprima.getCompraMateriaprimaList().remove(compraMateriaprimaListCompraMateriaprima);
                    oldMateriaprimaOfCompraMateriaprimaListCompraMateriaprima = em.merge(oldMateriaprimaOfCompraMateriaprimaListCompraMateriaprima);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(MateriaPrima materiaPrima) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            MateriaPrima persistentMateriaPrima = em.find(MateriaPrima.class, materiaPrima.getId());
            List<Fornecedor> fornecedorListOld = persistentMateriaPrima.getFornecedorList();
            List<Fornecedor> fornecedorListNew = materiaPrima.getFornecedorList();
            List<CompraMateriaprima> compraMateriaprimaListOld = persistentMateriaPrima.getCompraMateriaprimaList();
            List<CompraMateriaprima> compraMateriaprimaListNew = materiaPrima.getCompraMateriaprimaList();
            List<String> illegalOrphanMessages = null;
            for (CompraMateriaprima compraMateriaprimaListOldCompraMateriaprima : compraMateriaprimaListOld) {
                if (!compraMateriaprimaListNew.contains(compraMateriaprimaListOldCompraMateriaprima)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain CompraMateriaprima " + compraMateriaprimaListOldCompraMateriaprima + " since its materiaprima field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Fornecedor> attachedFornecedorListNew = new ArrayList<Fornecedor>();
            if(fornecedorListNew != null)//acrescentei esta linha
            for (Fornecedor fornecedorListNewFornecedorToAttach : fornecedorListNew) {
                fornecedorListNewFornecedorToAttach = em.getReference(fornecedorListNewFornecedorToAttach.getClass(), fornecedorListNewFornecedorToAttach.getCodigo());
                attachedFornecedorListNew.add(fornecedorListNewFornecedorToAttach);
            }
            fornecedorListNew = attachedFornecedorListNew;
            materiaPrima.setFornecedorList(fornecedorListNew);
            List<CompraMateriaprima> attachedCompraMateriaprimaListNew = new ArrayList<CompraMateriaprima>();
            if(compraMateriaprimaListNew != null)//acrescentei esta linha
            for (CompraMateriaprima compraMateriaprimaListNewCompraMateriaprimaToAttach : compraMateriaprimaListNew) {
                compraMateriaprimaListNewCompraMateriaprimaToAttach = em.getReference(compraMateriaprimaListNewCompraMateriaprimaToAttach.getClass(), compraMateriaprimaListNewCompraMateriaprimaToAttach.getCompraMateriaprimaPK());
                attachedCompraMateriaprimaListNew.add(compraMateriaprimaListNewCompraMateriaprimaToAttach);
            }
            compraMateriaprimaListNew = attachedCompraMateriaprimaListNew;
            materiaPrima.setCompraMateriaprimaList(compraMateriaprimaListNew);
            materiaPrima = em.merge(materiaPrima);
            for (Fornecedor fornecedorListOldFornecedor : fornecedorListOld) {
                if (!fornecedorListNew.contains(fornecedorListOldFornecedor)) {
                    fornecedorListOldFornecedor.getMateriaprimaList().remove(materiaPrima);
                    fornecedorListOldFornecedor = em.merge(fornecedorListOldFornecedor);
                }
            }
            for (Fornecedor fornecedorListNewFornecedor : fornecedorListNew) {
                if (!fornecedorListOld.contains(fornecedorListNewFornecedor)) {
                    fornecedorListNewFornecedor.getMateriaprimaList().add(materiaPrima);
                    fornecedorListNewFornecedor = em.merge(fornecedorListNewFornecedor);
                }
            }
            for (CompraMateriaprima compraMateriaprimaListNewCompraMateriaprima : compraMateriaprimaListNew) {
                if (!compraMateriaprimaListOld.contains(compraMateriaprimaListNewCompraMateriaprima)) {
                    MateriaPrima oldMateriaprimaOfCompraMateriaprimaListNewCompraMateriaprima = compraMateriaprimaListNewCompraMateriaprima.getMateriaprima();
                    compraMateriaprimaListNewCompraMateriaprima.setMateriaprima(materiaPrima);
                    compraMateriaprimaListNewCompraMateriaprima = em.merge(compraMateriaprimaListNewCompraMateriaprima);
                    if (oldMateriaprimaOfCompraMateriaprimaListNewCompraMateriaprima != null && !oldMateriaprimaOfCompraMateriaprimaListNewCompraMateriaprima.equals(materiaPrima)) {
                        oldMateriaprimaOfCompraMateriaprimaListNewCompraMateriaprima.getCompraMateriaprimaList().remove(compraMateriaprimaListNewCompraMateriaprima);
                        oldMateriaprimaOfCompraMateriaprimaListNewCompraMateriaprima = em.merge(oldMateriaprimaOfCompraMateriaprimaListNewCompraMateriaprima);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = materiaPrima.getId();
                if (findMateriaPrima(id) == null) {
                    throw new NonexistentEntityException("The materiaPrima with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            MateriaPrima materiaPrima;
            try {
                materiaPrima = em.getReference(MateriaPrima.class, id);
                materiaPrima.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The materiaPrima with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<CompraMateriaprima> compraMateriaprimaListOrphanCheck = materiaPrima.getCompraMateriaprimaList();
            for (CompraMateriaprima compraMateriaprimaListOrphanCheckCompraMateriaprima : compraMateriaprimaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This MateriaPrima (" + materiaPrima + ") cannot be destroyed since the CompraMateriaprima " + compraMateriaprimaListOrphanCheckCompraMateriaprima + " in its compraMateriaprimaList field has a non-nullable materiaprima field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Fornecedor> fornecedorList = materiaPrima.getFornecedorList();
            for (Fornecedor fornecedorListFornecedor : fornecedorList) {
                fornecedorListFornecedor.getMateriaprimaList().remove(materiaPrima);
                fornecedorListFornecedor = em.merge(fornecedorListFornecedor);
            }
            em.remove(materiaPrima);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<MateriaPrima> findMateriaPrimaEntities() {
        return findMateriaPrimaEntities(true, -1, -1);
    }

    public List<MateriaPrima> findMateriaPrimaEntities(int maxResults, int firstResult) {
        return findMateriaPrimaEntities(false, maxResults, firstResult);
    }

    private List<MateriaPrima> findMateriaPrimaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(MateriaPrima.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public MateriaPrima findMateriaPrima(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(MateriaPrima.class, id);
        } finally {
            em.close();
        }
    }

    public int getMateriaPrimaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<MateriaPrima> rt = cq.from(MateriaPrima.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
